package pl.edu.mimuw.irs.rcp.view.roles;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.gef.EditDomain;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.part.ViewPart;

import pl.edu.mimuw.irs.core.model.design.resource.Roles;
import pl.edu.mimuw.irs.rcp.controller.editor.roles.RolesTableWrapper;
import pl.edu.mimuw.irs.rcp.controller.editor.workflow.IRSWorkflowEditor;
import pl.edu.mimuw.irs.rcp.persistence.PersistenceManager;
import pl.edu.mimuw.irs.rcp.util.Logger;
import pl.edu.mimuw.irs.rcp.util.MessageCode;
import pl.edu.mimuw.irs.rcp.util.UITexts;

/**
 * @author Jakub Rauch
 * Created on: 2009-05-25
 */
public class RolesView extends ViewPart {

	public static final String ID = "pl.edu.mimuw.irs.view.roles";

	// *** Attributes
	
//	private IWorkbenchPart lastSourcepart;
	private ISelectionListener listener = new ISelectionListener() {
		@Override
		public void selectionChanged(IWorkbenchPart sourcepart, ISelection selection) {
//			if (sourcepart == lastSourcepart) return;
//			lastSourcepart = sourcepart;
//			if (!(sourcepart instanceof IEditorPart)) return;
//			if (sourcepart instanceof IRSWorkflowEditor) {
//				IRSWorkflowEditor editor = (IRSWorkflowEditor) sourcepart;
//				changeSelection(editor, selection);
//			}
		}
	};
	private IPartListener partListener = new IPartListener() {

		@Override
		public void partActivated(IWorkbenchPart sourcepart) {
			if (!(sourcepart instanceof IEditorPart)) return;
			if (sourcepart instanceof IRSWorkflowEditor) {
				IRSWorkflowEditor editor = (IRSWorkflowEditor) sourcepart;
				changeSelection(editor);
			}
		}

		@Override
		public void partBroughtToTop(IWorkbenchPart part) {
			
		}

		@Override
		public void partClosed(IWorkbenchPart part) {
			if (!(part instanceof IEditorPart)) return;
			editorClosed((IEditorPart) part);
		}

		@Override
		public void partDeactivated(IWorkbenchPart part) {
			
		}

		@Override
		public void partOpened(IWorkbenchPart part) {
			
		}
		
	};
	private Composite composite;
	private Button btnNewRole;
	private Text txtNewRole;
	private RolesTableWrapper tblRoles;
	private IEditorInput input;
	
	// *** Constructors

	public RolesView() {
		super();
	}

	// *** Methods

	private void editorClosed(IEditorPart editorPart) {
		if (editorPart.getEditorInput() == input) {
			input = null;
			tblRoles.setRoles(null);
			hide();
		}
	}
	
	private boolean isVisible() {
		return composite.getVisible();
	}
	
	private void hide() {
		composite.setVisible(false);
		setContentDescription(UITexts.get(MessageCode.ROLES_VIEW_UNASSIGNED_DESCRIPTION));
	}
	
	private void show() {
		composite.setVisible(true);
		setContentDescription("");
	}

	private void changeSelection(IRSWorkflowEditor sourcepart) {
		//setContentDescription(sourcepart.getTitle() + " (" + selection.getClass().getName() + ")");
		/*
		 * Get the IProject to access its session properties for Roles
		 */
		if (!(sourcepart instanceof IEditorPart)) return;
		IEditorPart editor = (IEditorPart) sourcepart;
		IEditorInput editorInput = editor.getEditorInput();
		Roles roles = loadRoles(editorInput);
		if (roles == null) return;
		
		/*
		 * Here we have roles.
		 */
		if (input != editorInput) input = editorInput;
		if (tblRoles.getRoles() != roles) {
			tblRoles.setEditDomain(sourcepart.getEditDomain());
			tblRoles.setRoles(roles);
			tblRoles.redrawTable();
			if (!isVisible()) show();
		}
	}
	
	private Roles loadRoles(IEditorInput input) {
		try {
			PersistenceManager manager = PersistenceManager.getInstance(input);
			if (manager == null) return null;
			return manager.getRoles();
		} catch (CoreException e) {
			Logger.handle(MessageCode.ROLES_LOAD_DESERIALIZE_PROBLEM, e, input);
			return null;
		} catch (Exception e) {
			Logger.handle(MessageCode.ROLES_LOAD_DESERIALIZE_PROBLEM, e, input);
			return null;
		}
	}
	
	/**
	 * This is a callback that will allow us to create the viewer and initialize
	 * it.
	 */
	public void createPartControl(Composite parent) {
		GridData gridData;
		composite = new Composite(parent, SWT.NULL);
		hide();
		
	    // create the desired layout for this wizard page
		GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 2;
		composite.setLayout(gridLayout);
		
		gridData = new GridData();
		gridData.horizontalAlignment = GridData.BEGINNING;
		
		btnNewRole = new Button(composite, SWT.PUSH);
		btnNewRole.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				addRole();
				super.widgetSelected(e);
			}
		});

		btnNewRole.setText(UITexts.get(MessageCode.ROLES_EDITOR_NEW));				
		txtNewRole = new Text(composite, SWT.BORDER);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		txtNewRole.setLayoutData(gridData);
		
		gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL);
		gridData.horizontalSpan = 2;
		tblRoles = new RolesTableWrapper(composite, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL, null, null);
		tblRoles.setLayoutData(gridData);
		getSite().setSelectionProvider(tblRoles.getTableViewer());
		
		getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(listener);
		getSite().getPage().addPartListener(partListener);

		TableViewer viewer = tblRoles.getTableViewer();
		MenuManager menuManager = new MenuManager();
		viewer.getTable().setMenu(menuManager.createContextMenu(viewer.getTable()));
		getSite().registerContextMenu(menuManager, viewer);
	}

	@Override
	public void dispose() {

		getSite().getWorkbenchWindow().getSelectionService().removeSelectionListener(listener);
		getSite().getPage().removePartListener(partListener);
		super.dispose();
	}
	
	private void addRole() {
		String name = txtNewRole.getText();
		if (name == null || name.equals("")) name = UITexts.get(MessageCode.ROLES_EDITOR_UNNAMED);
		tblRoles.addRole(name, true);
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		tblRoles.getTableViewer().getControl().setFocus();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public Object getAdapter(Class adapter) {
		if (adapter == CommandStack.class)
			if (tblRoles != null) return tblRoles.getCommandStack();
		else if (adapter == EditDomain.class)
			if (tblRoles != null) return tblRoles.getEditDomain();
		// the super implementation handles the rest
		return super.getAdapter(adapter);
	}
}
